package service

import (
	"errors"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"guns-go/global"
	"guns-go/model"
	"guns-go/model/request"
	"guns-go/model/response"
	"guns-go/utils"
)

func QuerySysPosById(posId int) (err error, sysOrg model.SysPos) {
	var pos model.SysPos
	err = global.GVA_DB.Where("id = ?", posId).Find(&pos).Error
	return err, pos
}

func CreateSysPos(pos *model.SysPos, tx *gorm.DB) error {
	return tx.Create(pos).Error
}

func UpdateSysPos(pos model.SysPos, tx *gorm.DB) error {
	return tx.Model(&pos).Updates(pos).Error
}

func SysPosList(sysPosParam *request.SysPosParam) (err error, s []*model.SysPos) {

	var posSlice []*model.SysPos

	db := global.GVA_DB

	if sysPosParam != nil {

		if sysPosParam.Code != "" {
			db = db.Where("code = ?", sysPosParam.Code)
		}
	}

	db = db.Where("status = ?", 0).Order("sort asc")

	err = db.Find(&posSlice).Error

	return err, posSlice
}

func PosPage(sysPosParam *request.SysPosParam, c *gin.Context) (err error, result *response.PageResult) {

	var sysPosSlice []*model.SysPos
	db := global.GVA_DB

	if sysPosParam != nil {

		//根据职位名称模糊查询
		if sysPosParam.Name != "" {
			db = db.Where("name like ?", "%"+sysPosParam.Name+"%")
		}

		//根据职位编码模糊查询
		if sysPosParam.Code != "" {
			db = db.Where("code like ?", "%"+sysPosParam.Code+"%")
		}
	}

	db = db.Where("status = ?", 0)

	//根据排序升序排列，序号越小越在前
	db.Order("sort asc")

	var totalCount int64

	err = db.Find(&sysPosSlice).Count(&totalCount).Error

	if err != nil {
		return err, nil
	}

	pageNo, pageSize, db := utils.DefaultPage(c, db)

	err = db.Find(&sysPosSlice).Error

	if err != nil {
		return err, nil
	}

	return err, utils.CoverToPageResult(pageNo, pageSize, totalCount, sysPosSlice)
}

func PosAdd(sysPosParam *request.SysPosParam) error {

	//校验参数，检查是否存在相同的名称和编码
	err := checkParamByPos(sysPosParam, false)

	if err != nil {
		return err
	}

	sysPos := new(model.SysPos)

	err = utils.SimpleCopyProperties(sysPos, sysPosParam)

	if err != nil {
		return err
	}

	var zero int8
	zero = 0

	sysPos.Status = &zero

	tx := global.GVA_DB.Begin()

	err = CreateSysPos(sysPos, tx)

	if err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

func PosEdit(sysPosParam *request.SysPosParam) error {

	err, sysPos := QuerySysPosById(sysPosParam.Id)

	if err != nil {
		return err
	}

	if sysPos.Id == 0 {
		return errors.New("职位不存在")
	}

	err = checkParamByPos(sysPosParam, true)

	if err != nil {
		return err
	}

	err = utils.SimpleCopyProperties(&sysPos, sysPosParam)

	if err != nil {
		return err
	}

	sysPos.Status = nil

	tx := global.GVA_DB.Begin()

	err = UpdateSysPos(sysPos, tx)

	if err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

func PosDelete(sysPosParam *request.SysPosParam) error {

	err, sysPos := QuerySysPosById(sysPosParam.Id)

	if err != nil {
		return err
	}

	if sysPos.Id == 0 {
		return errors.New("组织机构不存在")
	}

	id := sysPos.Id

	//该职位下是否有员工
	err, hasPosEmp := HasPosEmp(id)
	//只要还有，则不能删
	if hasPosEmp {
		return errors.New("该职位下有员工，无法删除")
	}

	//该附属职位下是否有员工
	err, hasExtPosEmp := HasExtPosEmp(id)
	//只要还有，则不能删
	if hasExtPosEmp {
		return errors.New("该职位下有员工，无法删除")
	}

	var two int8
	two = 2

	sysPos.Status = &two

	tx := global.GVA_DB.Begin()

	err = UpdateSysPos(sysPos, tx)

	if err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

func checkParamByPos(sysPosParam *request.SysPosParam, isExcludeSelf bool) error {

	id := sysPosParam.Id

	name := sysPosParam.Name
	code := sysPosParam.Code

	var sysPosSlice []*model.SysPos

	db := global.GVA_DB

	dbName := db.Where("name = ?", name).Where("status <> ?", 2)
	dbCode := db.Where("code = ?", code).Where("status <> ?", 2)

	if isExcludeSelf {
		dbName = dbName.Where("id <> ?", id)
		dbCode = dbCode.Where("id <> ?", id)
	}

	var countByName int64
	err := dbName.Find(&sysPosSlice).Count(&countByName).Error

	if err != nil {
		return err
	}

	var countByCode int64
	err = dbCode.Find(&sysPosSlice).Count(&countByCode).Error

	if err != nil {
		return err
	}

	if countByName >= 1 {
		return errors.New("职位名称重复，请检查name参数")
	}

	if countByCode >= 1 {
		return errors.New("职位编码重复，请检查code参数")
	}
	return nil
}
